package com.group.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.cloudauth.model.v20180504.*;
import com.aliyuncs.http.MethodType;
import com.base.view.BaseResult;
import com.base.view.GeneralResult;
import com.group.model.User;
import com.group.model.UserVerifyInfo;
import com.group.util.NoteException;

/**
 * 用户认证相关接口
 * 
 * @author zhaolei
 *
 */
@Controller
public class UserAuthController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(UserAuthController.class);

	/**
	 * 人脸验证接口
	 * 
	 * @param idNo
	 *            身份证号
	 * @param name
	 *            姓名
	 * @param front
	 *            证件照正面 完整url
	 * @param back
	 *            背面完整url
	 * @param face
	 *            自拍 完整url
	 *  {"code":"1","data":{"verifyStatus":{"statusCode":0}},"requestId":"B6A11338-7CD3-439C-BE92-89C8E142DE9F","success":true}
	 *         认证状态： 表示一个认证任务所处的认证状态，主要有以下四种状态： -1： 未认证，表示没有提交记录。 0：
	 *         认证中，表示已提交认证，系统正在审核认证资料。 1： 认证通过，表示最近一次提交的认证资料通过审核，当前认证任务完结。 2：
	 *         认证不通过，表示最近一次提交的认证资料未通过审核，当前认证任务还可以继续发起提交。
	 * @throws Exception
	 */

	/**
	 *
	 * @param idNo
	 * @param name
	 * @param front
	 * @param back
	 * @param face
	 * @param httpresponse
	 * @param httprequest
	 * @throws Exception
	 */
	@GetMapping("/user/auth")
	@ResponseBody
	public void auth(String idNo, String name, String front, String back, String face, HttpServletResponse httpresponse, HttpServletRequest httprequest) throws Exception {
		if (idNo == null) {
			throw new NoteException("身份证号不能为空");
		}
		User user = getUser(httprequest);
		UserVerifyInfo uinfo = beanDao.quickQueryOne(UserVerifyInfo.class, "idNo", idNo);
		if (uinfo != null && uinfo.getUserId().longValue() != user.getId().longValue()) {
			throw new NoteException("身份证号已经注册过");
		}

		String ticketId = UUID.randomUUID().toString(); // 认证ID, 由使用方指定,
														// 发起不同的认证任务需要更换不同的认证ID
		logger.info(" ticketId = " + ticketId);
		String token = null; // 认证token, 表达一次认证会话
		// 1. 发起认证请求, 获取到token
		// GetVerifyToken接口文档：https://help.aliyun.com/document_detail/57050.html
		GetVerifyTokenRequest getVerifyTokenRequest = new GetVerifyTokenRequest();
		getVerifyTokenRequest.setBiz(biz); // 传入采用RPMin认证方案的认证场景标识(biz)
		getVerifyTokenRequest.setTicketId(ticketId);
		GetVerifyTokenResponse tokenresponse = aclient.getAcsResponse(getVerifyTokenRequest);
		token = tokenresponse.getData().getVerifyToken().getToken(); // token默认30分钟时效，每次发起认证时都必须实时获取

		// 2. 用token提交认证材料
		// SubmitMaterials接口文档：https://help.aliyun.com/document_detail/58176.html
		SubmitMaterialsRequest submitRequest = new SubmitMaterialsRequest();
		submitRequest.setVerifyToken(token);
		// 若使用base64提交图片, 需要设置请求方法为POST
		submitRequest.setMethod(MethodType.POST);
		// 创建要提交的认证材料列表, 请根据 认证方案 中的说明传入相应字段
		List<SubmitMaterialsRequest.Material> verifyMaterials = new ArrayList<SubmitMaterialsRequest.Material>();

		SubmitMaterialsRequest.Material identificationNumber = new SubmitMaterialsRequest.Material();
		identificationNumber.setMaterialType("IdentificationNumber");
		identificationNumber.setValue(idNo);
		// identificationNumber.setValue("422432199210022595");
		verifyMaterials.add(identificationNumber);

		SubmitMaterialsRequest.Material mname = new SubmitMaterialsRequest.Material();
		mname.setMaterialType("Name");
		// mname.setValue("曹庆");
		mname.setValue(name);
		verifyMaterials.add(mname);

		SubmitMaterialsRequest.Material facePic = new SubmitMaterialsRequest.Material();
		facePic.setMaterialType("FacePic");
		// facePic.setValue("http://www.xn--gtv651d.com/api//file/download?fileId=20180606152322.jpg");
		facePic.setValue(face);
		verifyMaterials.add(facePic);

		SubmitMaterialsRequest.Material idCardFrontPic = new SubmitMaterialsRequest.Material();
		idCardFrontPic.setMaterialType("IdCardFrontPic");
		// idCardFrontPic.setValue("http://www.xn--gtv651d.com/api//file/download?fileId=20180606152318.jpg");
		// // http方式上传图片,
		// 此http地址须可公网访问
		idCardFrontPic.setValue(front);
		verifyMaterials.add(idCardFrontPic);

		SubmitMaterialsRequest.Material idCardBackPic = new SubmitMaterialsRequest.Material();
		idCardBackPic.setMaterialType("IdCardBackPic");
		// idCardBackPic.setValue("http://www.xn--gtv651d.com/api//file/download?fileId=20180606152312.jpg");
		// // oss方式上传图片,
		idCardBackPic.setValue(back);
		verifyMaterials.add(idCardBackPic);

		submitRequest.setMaterials(verifyMaterials);
		SubmitMaterialsResponse response = aclient.getAcsResponse(submitRequest);
		// 通常SubmitMaterials接口会同步返回认证结果，但是考虑到内部服务超时等情况，接口无法等到最终结果，会返回认证中状态,
		// 此时需要使用GetStatus接口轮询。
		// GetStatus接口文档：https://help.aliyun.com/document_detail/57049.html
		// GetStatusRequest getStatusRequest = new GetStatusRequest();
		// getStatusRequest.setBiz(biz);
		// getStatusRequest.setTicketId(ticketId);
		// GetStatusResponse response =
		// client.getAcsResponse(getStatusRequest);
		// int statusCode = response.getData().getStatusCode();
		// 后续业务处理

		// VerifyStatus status = response.getData().getVerifyStatus();

		logger.info("认证结果  = " + JSONObject.toJSONString(response));
		int code = response.getData().getVerifyStatus().getStatusCode();

		// 保存用户审核状态
		user.setVerifyStatus(code);
		beanDao.save(user);

		// 添加审核资料日志
		UserVerifyInfo info = beanDao.quickQueryOne(UserVerifyInfo.class, "userId", user.getId());
		if (info == null) {
			info = new UserVerifyInfo();
		}
		info.setUserId(user.getId());
		info.setName(name);
		info.setBack(back);
		info.setFront(front);
		info.setFace(face);
		info.setIdNo(idNo);
		info.setTicketId(ticketId);
		info.setStatue(code);
		beanDao.save(info);

		httpresponse.getWriter().write(JSONObject.toJSONString(response));
		httpresponse.getWriter().close();

	}

	/**
	 * 查询用户审核信息,包括结果
	 * 
	 * @param userId
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/user/auth/status")
	@ResponseBody
	public GeneralResult<UserVerifyInfo> getStatus(Long userId) throws Exception {

		return new GeneralResult<UserVerifyInfo>().setValue(beanDao.quickQueryOne(UserVerifyInfo.class, "userId", userId));
	}

}
